package it.polimi.meteocal_pappalardo_sacchi.bean;

import it.polimi.meteocal_pappalardo_sacchi.entity.*;

import javax.enterprise.context.RequestScoped;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Named
@ViewScoped
public class EventDetailsBean implements Serializable {

    @Inject
    UserBean userBean;
    @Inject
    NotificationManager notificationManager;
    @Inject
    EventManager eventManager;

    Invitation invitation;
    Event event;
    List<MeteoCalUser> joinedUserList;
    Long eventId;
    List<Notification> relatedNotificationList;
    boolean editInvitationAnswerAllowed;
    boolean isUserInvited;

    public void eventDetailsInit() {
        //se non supero il controllo di sicurezza, setto tutti i parametri a nuove entità vuote
        if (!showDetailsAllowanceCheck(eventId)) {
            event = new Event();
            joinedUserList = new ArrayList<MeteoCalUser>();
            relatedNotificationList = new ArrayList<Notification>();
            return;
        }
        event = eventManager.find(eventId);
        isUserInvited = eventManager.findAlreadyInvitedUserList(event).contains(userBean.getUser());
        if ((!(userBean.getUser().getUsername().equals(event.getCreator().getUsername()))) && isUserInvited) {
            invitation = notificationManager.findInvitationByUserAndEvent(userBean.getUser(), event);
        }
        joinedUserList = eventManager.findJoinedUserListByEvent(event);
        relatedNotificationList = notificationManager.findNotificationByUserAndEvent(userBean.getUser(), event);
        editInvitationAnswerAllowed = editInvitationAnswerCheck();
    }

    public boolean showDetailsAllowanceCheck(Long eventId) {
        Event event = eventManager.find(eventId);
        //se l'evento è pubblico chiunque può visualizzarlo
        if (event.isIsPublic()) {
            return true;
        } else {
            //se l'evento è privato solo gli invitati possono visualizzarlo
            if (event.getParticipantCalendarList().contains(userBean.getUser().getOwnedCalendar())) {
                return true;
            }
            return false;
        }
    }

    public void updateAcceptance() {
        if (editInvitationAnswerAllowed) {
            notificationManager.edit(invitation);
            //aggiorno la lista sulla base della modifica appena fatta
            joinedUserList = eventManager.findJoinedUserListByEvent(event);
        }
    }

    public boolean editInvitationAnswerCheck(){
        java.sql.Date today = java.sql.Date.valueOf(LocalDate.now(ZoneId.of("Europe/Paris")));
        java.sql.Time now = java.sql.Time.valueOf(LocalTime.now(ZoneId.of("Europe/Paris")));

        if (event.getStartingDate().after(today) ||
                        (event.getStartingDate().equals(today) && event.getStartingTime().after(now))) {
            return true;
        }
        return false;
    }

    public Invitation getInvitation() {
        return invitation;
    }

    public void setInvitation(Invitation invitation) {
        this.invitation = invitation;
    }

    public Event getEvent() {
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }

    public List<MeteoCalUser> getJoinedUserList() {
        return joinedUserList;
    }

    public Long getEventId() {
        return eventId;
    }

    public void setEventId(Long eventId) {
        this.eventId = eventId;
    }

    public void setJoinedUserList(List<MeteoCalUser> joinedUserList) {
        this.joinedUserList = joinedUserList;
    }

    public List<Notification> getRelatedNotificationList() {
        return relatedNotificationList;
    }

    public void setRelatedNotificationList(List<Notification> relatedNotificationList) {
        this.relatedNotificationList = relatedNotificationList;
    }

    public boolean isEditInvitationAnswerAllowed() {
        return editInvitationAnswerAllowed;
    }

    public void setEditInvitationAnswerAllowed(boolean editInvitationAnswerAllowed) {
        this.editInvitationAnswerAllowed = editInvitationAnswerAllowed;
    }

    public boolean isUserInvited() {
        return isUserInvited;
    }

    public void setUserInvited(boolean isUserInvited) {
        this.isUserInvited = isUserInvited;
    }
}
